#include "WProgram.h"
#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 
void setup();
void loop();
int SWread();
void SWprint(int data);
void selectLineOne();
void selectLineTwo();
void clearLCD();
void backlightOn();
void backlightOff();
void serCommand();
byte rx = 6;
byte tx = 7;
byte SWval;

int incomingByte = 0;	// for incoming serial data

void setup()
{
  Serial.begin(9600);
  backlightOn();
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  digitalWrite(13,HIGH); //turn on debugging LED
  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint(10); //carriage return

  
}

void loop()
{  
  

    SWval = SWread(); 
    SWprint(toupper(SWval));

  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
 delay(100);
    // say what you got:
    selectLineOne();
     delay(100);
   // Serial.print("I received: ");
    selectLineTwo();
    delay(100);
   // Serial.print(incomingByte, BYTE);
     delay(100);
  }
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
  Serial.print(0xFE, BYTE);   //command flag
  Serial.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
  Serial.print(0xFE, BYTE);   //command flag
  Serial.print(192, BYTE);    //position
}
void clearLCD(){
  Serial.print(0xFE, BYTE);   //command flag
  Serial.print(0x01, BYTE);   //clear command.
}
void backlightOn(){  //turns on the backlight
  Serial.print(0x7C, BYTE);   //command flag for backlight stuff
  Serial.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
  Serial.print(0x7C, BYTE);   //command flag for backlight stuff
  Serial.print(128, BYTE);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.print(0xFE, BYTE);
}

int main(void)
{
	init();

	setup();
    
	for (;;)
		loop();
        
	return 0;
}

